Git: advanced concepts

In a nutshell

  1. Versioning: keep every change made to files
  2. Branching: develop new features while fixing bugs on a production release
  3. Decentralized & Collaborative

Outline

  1. Git internals
  2. 5-min break
  3. Common commands
  4. 5-min break
  5. Tips and tricks for efficient programming



Git internals

What’s Git?

First of all, Git lives in .git/

What’s Git?

Second of all, Git “is” a tree of commits.

What’s a commit then?

SHA-1

SHA-1 is an algorithm that takes some data as input and generates a unique 40 character string from it.

The SHA-1 hash depends on…

  1. The commit message
  2. The committer info
  3. The commit date
  4. The author info
  5. The authoring date
  6. The source tree (= the state of the code)
  7. The commit’s parent commits


If any of these values change, the SHA-1 changes.

https://blog.thoughtram.io/git/2014/11/18/the-anatomy-of-a-git-commit.html

What’s Git again?

What’s Git again?

  1. Git holds a tree of commits

What’s Git again?

  1. Git holds a tree of commits
  2. Commits have 1 or 2 parents tops

What’s Git again?

  1. Git holds a tree of commits
  2. Commits have 1 or 2 parents tops
  3. There are special cases of orphan commits (no parents) such as the first commit

What’s Git again?

  1. Git holds a tree of commits
  2. Commits have 1 or 2 parents tops
  3. There are special cases of orphan commits (no parents) such as the first commit
  4. A branch is a label/tag/pointer/reference (pick the word of your liking) pointing towards a commit

Two types of branches

  1. Local writable branches
  2. Distant read-only branches (prefixed with origin/)

Special pointers

HEAD~ vs HEAD^

www.paulboxley.com/blog/2011/06/git-caret-and-tilde

Let’s look under the hood

Remember: Git lives in .git/

$ lstree .git/refs
.git/refs
     +--- remotes
     |   +--- origin
     |   |   +--- DOC-38-FIX
     |   |   +--- master
     |   |   +--- PAT-256
     |   |   +--- production
     +--- tags
     |   +--- first-commit
     +--- heads
     |   +--- master
     |   +--- feature-xyz
     |   +--- production
$ cat .git/refs/heads/master
fgjh75955bd59c7ef27d0c55b9165db6a2b768ce


$ cat .git/HEAD
ref: refs/heads/feature-xyz

Everything is a pointer pointing at a commit.

Common commands

How to commit?

Some vocabulary first

git fetch

git pull

= git fetch + git merge

git merge

To fast forward, or not to fast forward…

git rebase

Rebasing rewrites history.

git diff

git show

git checkout

git branch

git merge-base

git merge-base origin/master HEAD


==> Common ancestor between origin/master & HEAD

(= between your branch and master)

git revert <SHA-1>






git stash

git log

git reset

git bisect

Finds the commit which introduced a bug.

git reflog

History of all actions performed.

Tips and tricks

for efficient programming

Use the CLI and RTFM

Forget about the GUI

man git-merge

git rebase -i $(git merge-base origin/master HEAD)

When you want to edit/squash some commits and leave other untouched, while keeping most SHA-1 hashes

git lg

github.com/rpellerin/dotfiles/blob/master/.gitconfig

hub pull-request

github.com/github/hub

Delete merged branches

git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -D

Open last modified files

https://github.com/rpellerin/dotfiles/blob/master/.aliases

Built-in aliases for common Git commands

alias | grep git

(go ahead, run the command right now)

That’s it! Thanks.